using NodeCanvas.StateMachines;
using UnityEngine;

namespace NodeCanvas.BehaviourTrees
{
	[AddComponentMenu("")]
	[Name("FSM")]
	[Category("Nested")]
	[Description("NestedFSM can be assigned an entire FSM. This node will return Running for as long as the FSM is Running. If a Success or Failure State is selected, then it will return Success or Failure as soon as the Nested FSM enters that state at which point the FSM will also be stoped. Otherwise, if the Nested FSM ends this node will return Success.")]
	[Icon("FSM")]
	public class BTNestedFSMNode : BTNodeBase, INestedNode
	{
		[SerializeField]
		private FSM _nestedFSM;

		private bool instantiated;

		public string successState;

		public string failureState;

		private FSM nestedFSM
		{
			get
			{
				return _nestedFSM;
			}
			set
			{
				_nestedFSM = value;
				if (_nestedFSM != null)
				{
					_nestedFSM.agent = base.graphAgent;
					_nestedFSM.blackboard = base.graphBlackboard;
				}
			}
		}

		public Graph nestedGraph
		{
			get
			{
				return nestedFSM;
			}
			set
			{
				nestedFSM = (FSM)value;
			}
		}

		public override string nodeName
		{
			get
			{
				return base.nodeName.ToUpper();
			}
		}

		protected override Status OnExecute(Component agent, Blackboard blackboard)
		{
			if (nestedFSM == null || nestedFSM.primeNode == null)
			{
				return Status.Failure;
			}
			CheckInstance();
			if (base.status == Status.Resting || nestedFSM.isPaused)
			{
				base.status = Status.Running;
				nestedFSM.StartGraph(agent, blackboard, OnFSMFinish);
			}
			if (!string.IsNullOrEmpty(successState) && nestedFSM.currentStateName == successState)
			{
				nestedFSM.StopGraph();
				return Status.Success;
			}
			if (!string.IsNullOrEmpty(failureState) && nestedFSM.currentStateName == failureState)
			{
				nestedFSM.StopGraph();
				return Status.Failure;
			}
			return base.status;
		}

		private void OnFSMFinish()
		{
			if (base.status == Status.Running)
			{
				base.status = Status.Success;
			}
		}

		protected override void OnReset()
		{
			if ((bool)nestedFSM)
			{
				nestedFSM.StopGraph();
			}
		}

		public override void OnGraphStarted()
		{
			if ((bool)nestedFSM)
			{
				CheckInstance();
			}
		}

		public override void OnGraphPaused()
		{
			if ((bool)nestedFSM)
			{
				nestedFSM.PauseGraph();
			}
		}

		public override void OnGraphStoped()
		{
			if ((bool)nestedFSM)
			{
				nestedFSM.StopGraph();
			}
		}

		private void CheckInstance()
		{
			if (!instantiated && nestedFSM != null && nestedFSM.transform.parent != base.graph.transform)
			{
				nestedFSM = Object.Instantiate(nestedFSM, base.transform.position, base.transform.rotation);
				nestedFSM.transform.parent = base.graph.transform;
				instantiated = true;
			}
		}
	}
}
